﻿using SQLite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using TabbedTemplate.Models;

namespace TabbedTemplate.Services
{
    public class BeijingCacheService : IBeijingCacheService
    {
        /// <summary>
        /// 北京的缓存。
        /// </summary>
        public const string BeijingCacheDbName = "BeijingCacheDb.sqlite3";

        /// <summary>
        /// 北京缓存的路径。
        /// </summary>
        public static readonly string BeijingCacheDbPath =
            Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder
                    .LocalApplicationData), BeijingCacheDbName);

        /// <summary>
        /// 数据库连接影子变量。
        /// </summary>
        private SQLiteAsyncConnection _beijingConnection;

        /// <summary>
        /// 数据库连接。
        /// </summary>
        private SQLiteAsyncConnection BeijingConnection =>
            _beijingConnection ?? (_beijingConnection =
                new SQLiteAsyncConnection(BeijingCacheDbPath));

        // ******** 构造函数。
        /// <summary>
        /// 构造函数。
        /// </summary>
        /// <param name="preferenceStorage"></param>
        public BeijingCacheService(IPreferenceStorage preferenceStorage)
        {
            _preferenceStorage = preferenceStorage;
        }

        private IPreferenceStorage _preferenceStorage;

        public bool BeijingInitialized() =>
            _preferenceStorage.Get(BeijingCacheConstants.VersionKey, -1) ==
            BeijingCacheConstants.Version;

        public async Task InitializeBeijingAsync()
        {
            //打开文件流。
            using var dbFileStream =
                new FileStream(BeijingCacheDbPath, FileMode.Create);
            //打开资源流。
            using var dbAssertStream = Assembly.GetExecutingAssembly()
                .GetManifestResourceStream(BeijingCacheDbName);
            //将资源流中的内容拷贝到文件流中。
            await dbAssertStream.CopyToAsync(dbFileStream);

            _preferenceStorage.Set(BeijingCacheConstants.VersionKey,
                BeijingCacheConstants.Version);
        }

        public async Task<Store> GetBeijingStoreAsync(string uid) =>
            await BeijingConnection.Table<Store>()
                .FirstOrDefaultAsync(p => p.Uid == uid);


        // 获取满足给定条件的店铺集合。
        /// <param name="where">Where条件。</param>
        /// <param name="skip">跳过数量。</param>
        /// <param name="take">获取数量。</param>
        /// Expression 表达式 函数，参数，返回值
        /// Where 万能查找
        /// where条件，跳过多少条，返回多少条
        public async Task<IList<Store>> GetBeijingStoresAsync(
            Expression<Func<Store, bool>> @where, int skip, int take) =>
            await BeijingConnection.Table<Store>().Where(@where).Skip(skip)
                .Take(take).ToListAsync();

        public async Task<IList<Store>> GetBeijingStoreByTagAsync(string Tag, int skip, int take) =>
            await BeijingConnection.Table<Store>().Where(p => p.Tag == Tag)
                .Skip(skip).Take(take).ToListAsync();

        public async Task CloseAsync() => await BeijingConnection.CloseAsync();
    }
}
